//-----------------------------------------------
//    module name: socmem
//    author: 
//  
//    version: 1st version (2021-10-01)
//    description: 
//        
//
//
//-----------------------------------------------
`timescale 1ns / 1ps

module socmem(
    input  wire        rstn,
    input  wire        clk,
    
    input  wire [ 3:0] i_iwen_4,          
    input  wire [31:0] i_iaddress_32, 
    input  wire [31:0] i_idataW_32,  
    output wire [31:0] o_idataR_32,
    
    input  wire [ 3:0] i_dwen_4,          
    input  wire [31:0] i_daddress_32, 
    input  wire [31:0] i_ddataW_32,  
    output wire [31:0] o_ddataR_32,
    
    input  wire        req_valid_i,
    output wire        rsp_valid_o
    );
    integer i;    
    
`ifdef VIVADO_ENV
    `ifdef BEHAVIOR_SIMULATION         
      
       reg  [31:0] mem [0:16383];
       reg  [31:0] r_idata_32;
       
       always @ (posedge clk or negedge rstn) begin
            if(!rstn) begin end
            else if(|i_iwen_4) begin
                if(i_iwen_4[0]) begin mem[{1'b0,i_iaddress_32[14:2]}][7:0]   <=  i_idataW_32[7:0]; 
                end else        begin mem[{1'b0,i_iaddress_32[14:2]}][7:0]   <=  mem[{1'b0,i_iaddress_32[14:2]}][7:0];  end
                if(i_iwen_4[1]) begin mem[{1'b0,i_iaddress_32[14:2]}][15:8]  <=  i_idataW_32[15:8]; 
                end else        begin mem[{1'b0,i_iaddress_32[14:2]}][15:8]  <=  mem[{1'b0,i_iaddress_32[14:2]}][15:8]; end
                if(i_iwen_4[2]) begin mem[{1'b0,i_iaddress_32[14:2]}][23:16] <=  i_idataW_32[23:16]; 
                end else        begin mem[{1'b0,i_iaddress_32[14:2]}][23:16] <=  mem[{1'b0,i_iaddress_32[14:2]}][23:16];end
                if(i_iwen_4[3]) begin mem[{1'b0,i_iaddress_32[14:2]}][31:24] <=  i_idataW_32[31:24]; 
                end else        begin mem[{1'b0,i_iaddress_32[14:2]}][31:24] <=  mem[{1'b0,i_iaddress_32[14:2]}][31:24];end
            end
        end
       
        always @ (posedge clk or negedge rstn) begin      
            if(!rstn) begin
                r_idata_32 <= `nop;      
            end else
                r_idata_32 <= mem[{1'b0,i_iaddress_32[14:2]}];
        end
        assign o_idataR_32 = r_idata_32;
        
        //reg [31:0] mem [0:8191];
        reg [31:0] r_ddata_32; 
        
        always @ (posedge clk or negedge rstn) begin    
            if(!rstn) begin  end
            else if(i_dwen_4) begin
                if(i_dwen_4[0]) begin mem[{1'b1,i_daddress_32[14:2]}][7:0]   <=  i_ddataW_32[7:0]; 
                end else        begin mem[{1'b1,i_daddress_32[14:2]}][7:0]   <=  mem[{1'b1,i_daddress_32[14:2]}][7:0]; end
                if(i_dwen_4[1]) begin mem[{1'b1,i_daddress_32[14:2]}][15:8]  <=  i_ddataW_32[15:8]; 
                end else        begin mem[{1'b1,i_daddress_32[14:2]}][15:8]  <=  mem[{1'b1,i_daddress_32[14:2]}][15:8]; end
                if(i_dwen_4[2]) begin mem[{1'b1,i_daddress_32[14:2]}][23:16] <=  i_ddataW_32[23:16]; 
                end else        begin mem[{1'b1,i_daddress_32[14:2]}][23:16] <=  mem[{1'b1,i_daddress_32[14:2]}][23:16]; end
                if(i_dwen_4[3]) begin mem[{1'b1,i_daddress_32[14:2]}][31:24] <=  i_ddataW_32[31:24]; 
                end else        begin mem[{1'b1,i_daddress_32[14:2]}][31:24] <=  mem[{1'b1,i_daddress_32[14:2]}][31:24]; end
            end
        end
        
        always @ (posedge clk or negedge rstn) begin    
            if(!rstn) begin
                 r_ddata_32 <= 32'b0;
            end else
                 r_ddata_32 <= mem[{1'b1,i_daddress_32[14:2]}];
        end
         assign o_ddataR_32 = r_ddata_32;
         
     `endif
     `ifdef POST_SYNTHSIS_SIMULATION //FPGA BRAM

     mem_dualportBRAM cache(
            .addra({1'b0,i_iaddress_32[14:2]}),
            .clka(clk),
            .dina(i_idataW_32),
            .douta(o_idataR_32),
            .wea(i_iwen_4),
            
            .addrb({1'b1,i_daddress_32[14:2]}),
            .clkb(clk),
            .dinb(i_ddataW_32),
            .doutb(o_ddataR_32),
            .web(i_dwen_4)
         );
     `endif
 `else 
     `ifdef DC_ENV

    wire [31:0] o_idataR_t_32; 

  // UMC .11um  SRAM ip
        SHTB110_8192X8X4CM16 icache (
            .A0(i_iaddress_32[2]),.A1(i_iaddress_32[3]),.A2(i_iaddress_32[4]),.A3(i_iaddress_32[5]),
            .A4(i_iaddress_32[6]),.A5(i_iaddress_32[7]),.A6(i_iaddress_32[8]),.A7(i_iaddress_32[9]),
            .A8(i_iaddress_32[10]),.A9(i_iaddress_32[11]),.A10(i_iaddress_32[12]),.A11(i_iaddress_32[13]),.A12(i_iaddress_32[14]),
            .DO0(o_idataR_t_32[0]),.DO1(o_idataR_t_32[1]),.DO2(o_idataR_t_32[2]),.DO3(o_idataR_t_32[3]),.DO4(o_idataR_t_32[4]),
            .DO5(o_idataR_t_32[5]),.DO6(o_idataR_t_32[6]),.DO7(o_idataR_t_32[7]),.DO8(o_idataR_t_32[8]),.DO9(o_idataR_t_32[9]),
            .DO10(o_idataR_t_32[10]),.DO11(o_idataR_t_32[11]),.DO12(o_idataR_t_32[12]),.DO13(o_idataR_t_32[13]),.DO14(o_idataR_t_32[14]),
            .DO15(o_idataR_t_32[15]),.DO16(o_idataR_t_32[16]),.DO17(o_idataR_t_32[17]),.DO18(o_idataR_t_32[18]),.DO19(o_idataR_t_32[19]),
            .DO20(o_idataR_t_32[20]),.DO21(o_idataR_t_32[21]),.DO22(o_idataR_t_32[22]),.DO23(o_idataR_t_32[23]),.DO24(o_idataR_t_32[24]),
            .DO25(o_idataR_t_32[25]),.DO26(o_idataR_t_32[26]),.DO27(o_idataR_t_32[27]),.DO28(o_idataR_t_32[28]),.DO29(o_idataR_t_32[29]),
            .DO30(o_idataR_t_32[30]),.DO31(o_idataR_t_32[31]),
            .DI0(i_idataW_32[0]),.DI1(i_idataW_32[1]),.DI2(i_idataW_32[2]),.DI3(i_idataW_32[3]),.DI4(i_idataW_32[4]),.DI5(i_idataW_32[5]),
            .DI6(i_idataW_32[6]),.DI7(i_idataW_32[7]),.DI8(i_idataW_32[8]),.DI9(i_idataW_32[9]),.DI10(i_idataW_32[10]),.DI11(i_idataW_32[11]),
            .DI12(i_idataW_32[12]),.DI13(i_idataW_32[13]),.DI14(i_idataW_32[14]),.DI15(i_idataW_32[15]),.DI16(i_idataW_32[16]),
            .DI17(i_idataW_32[17]),.DI18(i_idataW_32[18]),.DI19(i_idataW_32[19]),.DI20(i_idataW_32[20]),.DI21(i_idataW_32[21]),
            .DI22(i_idataW_32[22]),.DI23(i_idataW_32[23]),.DI24(i_idataW_32[24]),.DI25(i_idataW_32[25]),.DI26(i_idataW_32[26]),
            .DI27(i_idataW_32[27]),.DI28(i_idataW_32[28]),.DI29(i_idataW_32[29]),.DI30(i_idataW_32[30]),.DI31(i_idataW_32[31]),
            .WEB0(~i_iwen_4[0]),.WEB1(~i_iwen_4[1]),.WEB2(~i_iwen_4[2]),.WEB3(~i_iwen_4[3]),
            .DVSE(1'b0),
            .DVS0(1'b0),.DVS1(1'b0),.DVS2(1'b0),.DVS3(1'b0),
            .CK(clk),
            .CSB(1'b0),
            .OE(1'b1));

        assign o_idataR_32 =  (o_idataR_t_32 ==32'b0) ? `nop :o_idataR_t_32; 
        
        wire [31:0] o_ddataR_t_32; 
                  
               // UMC .11um  SRAM ip
        SHTB110_8192X8X4CM16 dcache (
            .A0(i_daddress_32[2]),.A1(i_daddress_32[3]),.A2(i_daddress_32[4]),.A3(i_daddress_32[5]),
            .A4(i_daddress_32[6]),.A5(i_daddress_32[7]),.A6(i_daddress_32[8]),.A7(i_daddress_32[9]),
            .A8(i_daddress_32[10]),.A9(i_daddress_32[11]),.A10(i_daddress_32[12]),.A11(i_daddress_32[13]),.A12(i_daddress_32[14]),
            .DO0(o_ddataR_t_32[0]),.DO1(o_ddataR_t_32[1]),.DO2(o_ddataR_t_32[2]),.DO3(o_ddataR_t_32[3]),.DO4(o_ddataR_t_32[4]),
            .DO5(o_ddataR_t_32[5]),.DO6(o_ddataR_t_32[6]),.DO7(o_ddataR_t_32[7]),.DO8(o_ddataR_t_32[8]),.DO9(o_ddataR_t_32[9]),
            .DO10(o_ddataR_t_32[10]),.DO11(o_ddataR_t_32[11]),.DO12(o_ddataR_t_32[12]),.DO13(o_ddataR_t_32[13]),.DO14(o_ddataR_t_32[14]),
            .DO15(o_ddataR_t_32[15]),.DO16(o_ddataR_t_32[16]),.DO17(o_ddataR_t_32[17]),.DO18(o_ddataR_t_32[18]),.DO19(o_ddataR_t_32[19]),
            .DO20(o_ddataR_t_32[20]),.DO21(o_ddataR_t_32[21]),.DO22(o_ddataR_t_32[22]),.DO23(o_ddataR_t_32[23]),.DO24(o_ddataR_t_32[24]),
            .DO25(o_ddataR_t_32[25]),.DO26(o_ddataR_t_32[26]),.DO27(o_ddataR_t_32[27]),.DO28(o_ddataR_t_32[28]),.DO29(o_ddataR_t_32[29]),
            .DO30(o_ddataR_t_32[30]),.DO31(o_ddataR_t_32[31]),
            .DI0(i_ddataW_32[0]),.DI1(i_ddataW_32[1]),.DI2(i_ddataW_32[2]),.DI3(i_ddataW_32[3]),.DI4(i_ddataW_32[4]),.DI5(i_ddataW_32[5]),
            .DI6(i_ddataW_32[6]),.DI7(i_ddataW_32[7]),.DI8(i_ddataW_32[8]),.DI9(i_ddataW_32[9]),.DI10(i_ddataW_32[10]),.DI11(i_ddataW_32[11]),
            .DI12(i_ddataW_32[12]),.DI13(i_ddataW_32[13]),.DI14(i_ddataW_32[14]),.DI15(i_ddataW_32[15]),.DI16(i_ddataW_32[16]),
            .DI17(i_ddataW_32[17]),.DI18(i_ddataW_32[18]),.DI19(i_ddataW_32[19]),.DI20(i_ddataW_32[20]),.DI21(i_ddataW_32[21]),
            .DI22(i_ddataW_32[22]),.DI23(i_ddataW_32[23]),.DI24(i_ddataW_32[24]),.DI25(i_ddataW_32[25]),.DI26(i_ddataW_32[26]),
            .DI27(i_ddataW_32[27]),.DI28(i_ddataW_32[28]),.DI29(i_ddataW_32[29]),.DI30(i_ddataW_32[30]),.DI31(i_ddataW_32[31]),
            .WEB0(~i_dwen_4[0]),.WEB1(~i_dwen_4[1]),.WEB2(~i_dwen_4[2]),.WEB3(~i_dwen_4[3]),
            .DVSE(1'b0),
            .DVS0(1'b0),.DVS1(1'b0),.DVS2(1'b0),.DVS3(1'b0),
            .CK(clk),
            .CSB(1'b0),
            .OE(1'b1));

        assign o_ddataR_32 = o_ddataR_t_32;
        
    `endif
`endif
    reg vld_r;
    always @ (posedge clk or negedge rstn) begin  
        if(!rstn) begin
            vld_r <= 1'b0;
        end else begin
            vld_r <= req_valid_i;
        end
    end        
    assign rsp_valid_o = vld_r;

endmodule

